#include "pipe_use.hpp"
#include <string>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <ctime>
#include <sys/stat.h>
#include <sys/wait.h>

const int processnumber = 10; 
std::vector<task_t> tasks;

class channel
{
public:
    channel(int cmdfd, int slaverid, const std::string processname)
        : _cmdfd(cmdfd)
        , _slaverid(slaverid)
        , _processname(processname)
    {}

    int _cmdfd;
    int _slaverid;
    std::string _processname;
};

void slaver()
{
    while (true)
    {
        int cmdcode = 0;
        int n = read(0, &cmdcode, sizeof(int));
        if (n == sizeof(int))
        {
            std::cout << "child get message from father" << " the message is " << std::endl;
            if (cmdcode >= 0 && cmdcode < 4) tasks[cmdcode]();
        }
        if (n == 0) break;
    }
}

void initchannel(std::vector<channel>& channels)
{
    std::vector<int> oldfd;
    for (int i = 0; i < processnumber; i++)
    {
        int pipefd[2];
        int n = pipe(pipefd);

        pid_t id = fork();
        if (id == 0)
        {
            for (auto fd : oldfd) close(fd);
            close(pipefd[1]);
            dup2(pipefd[0], 0);
            close(pipefd[0]);

            slaver();
            exit(0);
        }

        close(pipefd[0]);
        std::string processname = "process-" + std::to_string(i);
        channels.push_back(channel(pipefd[1], id, processname));
        oldfd.push_back(pipefd[1]);
    }
}

void menu()
{
    std::cout << "1. 日志   2. 野区 " << std::endl;
    std::cout << "3. 更新   4. 技能 " << std::endl;
}

void control_slaver(const std::vector<channel>& channels)
{
    int which = 0;
    while (true)
    {
        int cmdcode = 0;
        menu();
        std::cout << "please enter# "; std::cin >> cmdcode;
        --cmdcode;

        if (cmdcode < 0 || cmdcode > 3)  break;

        write(channels[which]._cmdfd, &cmdcode, sizeof(cmdcode));
        which++;
        which %= channels.size();

        sleep(1);
    }
}

void quit_process(std::vector<channel>& channels)
{
    for (auto ch : channels)
    {
        close(ch._cmdfd);
        waitpid(ch._slaverid, nullptr, 0);
    }
}

int main()
{
    loadTask(tasks);

    std::vector<channel> channels;
    initchannel(channels);

    control_slaver(channels);

    quit_process(channels);
    
    return 0;
}

